package com.strategy.strategy.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.strategy.Abstract.AbstractUploadStrategyImpl;
import com.strategy.config.ObjectStoreProperties;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

/**
 * ClassName:OssUploadStrategyImpl
 * Package:com.strategy.strategy.impl
 * Description
 *
 * @Author:@wenxueshi
 * @Create:2023/7/16 - 22:16
 * @Version:v1.0
 */
@Slf4j
@Getter
@Setter
@RequiredArgsConstructor
@Service("MinioUploadServiceImpl")
public class MinioUploadStrategyImpl extends AbstractUploadStrategyImpl {

    /**
     * 构造器注入bean
     */
    private final ObjectStoreProperties properties;

    /**
     * 当前类的属性
     */
    private MinioClient minioClient;


    //初始化Minio对象
    @Override
    public void initClient() {
        minioClient = MinioClient.builder()
                .endpoint(properties.getMinio().getEndpoint())
                .credentials(properties.getMinio().getAccessKey(),
                             properties.getMinio().getSecretKey())
                .build();
        log.info("OssClient Init Success...");
    }

    @Override
    public boolean checkFileIsExisted(String fileRelativePath) {
        return true;
    }

    //Minio方式上传逻辑
    @Override
    public String executeUpload(MultipartFile file) {
        log.info("File Upload Starts...");
        String fileName = file.getOriginalFilename();
        //必须写出\\.这是转义，将文件名2.jpg从.开始分割成 2 和 jpg
        String[] split = fileName.split("\\.");
        if (split.length > 1) {
            //防止文件重名：添加系统时间：文件名为：2_37598375837.jpg
            //方式1：
            //fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1];
            //方式2：
            // 完善1、 --> 在文件名中添加唯一值
            String uuid = UUID.randomUUID().toString().replace("-", "");
            fileName = uuid + split[0] + "." + split[1];
            // 完善2、 --> 把文件按照日期分类
            String datePath = new DateTime().toString("yyyy/MM/dd");
            // 拼接时间 yyyy/MM/dd/filename
            fileName = datePath + "/" + fileName;
        } else {
            fileName = fileName + System.currentTimeMillis();
        }
        InputStream in = null;
        try {
            //开始上传
            in = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(properties.getMinio().getBucketname())
                    .object(fileName)
                    .stream(in, in.available(), -1)
                    .contentType(file.getContentType())
                    .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        fileName = properties.getMinio().getEndpoint() + "/" + properties.getMinio().getBucketname() + "/" + fileName;
        log.info("File Upload Finish...");
        //最后文件返回路径：http://localhost:9000/test/2023/07/20/06a415a221804ceebe8048d015c97f9a1.jpg
        return fileName;
    }

    //返回文件访问公网地址
    @Override
    public String getPublicNetworkAccessUrl(String fileRelativePath) {
        return fileRelativePath;
    }
}

